package com.example.common.mvi

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.net.event.Event
import com.example.net.event.bus
import java.lang.reflect.ParameterizedType

@Suppress("UNCHECKED_CAST")
abstract class BaseFragment<B: ViewDataBinding,VM:BaseViewModel<*,*>>:Fragment() {
	val types by lazy {
		(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments
	}

	val viewModel:VM by lazy {
		val clazz = types[1] as Class<VM>
		ViewModelProvider(this)[clazz]
	}
	val binding:B by lazy {
		val clazz = types[0] as Class<B>
		clazz.getMethod("inflate", LayoutInflater::class.java).invoke(null,layoutInflater) as B
	}
	override fun onCreateView(
		inflater: LayoutInflater,
		container: ViewGroup?,
		savedInstanceState: Bundle?
	): View?  = binding.root
	
	override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
		super.onViewCreated(view, savedInstanceState)
		observable()
		initData()
		initView()
	}
	private fun observable() {
		val methods = javaClass.declaredMethods
		for (method in methods){
			val event = method.getAnnotation(Event::class.java)
			if(event != null){
				bus.observe(viewLifecycleOwner){
					if(it.first == event.value){
						method.invoke(this,it.second)
					}
				}
			}
		}
	}
	abstract fun initView()
	
	abstract fun initData()
}